portal Michała Hanćkowiaka
Begin main content
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>

#define PORT htons(21212)

void ObsluzPolaczenie(int gn) //ServeConnection
{
    char sciezka[512]; //path (for a file)
    long dl_pliku, wyslano, wyslano_razem, przeczytano;
    struct stat fileinfo;
    FILE* plik; //file
    unsigned char bufor[1024]; //buffer

    memset(sciezka, 0, 512); //path
    if (recv(gn, sciezka, 512, 0) <= 0)
    {
    printf("Potomny: blad przy odczycie sciezki\nChild (process): error while reading a path\n");
    return;
    }

    printf("Potomny: klient chce plik (Child: client wants a file) %s\n", sciezka);

    if (stat(sciezka, &fileinfo) < 0)
    {
    printf("Potomny: nie moge pobrac informacji o pliku\n(Child: I can't obtain information about a file)\n");
    return;
    }

    if (fileinfo.st_size == 0)
    {
    printf("Potomny: rozmiar pliku (child: filesize) 0\n");
    return;
    }

    printf("Potomny: dlugosc pliku (child: filesize): %d\n", fileinfo.st_size);

    dl_pliku = htonl((long) fileinfo.st_size);

    if (send(gn, &dl_pliku, sizeof(long), 0) != sizeof(long))
    {
    printf("Potomny: blad przy wysylaniu wielkosci pliku (error at sending a file)\n");
    return;
    }

    dl_pliku = fileinfo.st_size;
    wyslano_razem = 0;
    plik = fopen(sciezka, "rb");
    if (plik == NULL)
    {
    printf("Potomny: blad przy otwarciu pliku (error at opening a file)\n");
    return;
    }

    while (wyslano_razem < dl_pliku)
    {
    przeczytano = fread(bufor, 1, 1024, plik);
    wyslano = send(gn, bufor, przeczytano, 0); //sent, buffer, read
    if (przeczytano != wyslano) //read (received) !=sent
        break;
    wyslano_razem += wyslano;
    printf("Potomny: wyslano %ld bajtow (total sent)\n", wyslano_razem);
    }

    if (wyslano_razem == dl_pliku)
    printf("Potomny: plik wyslany poprawnie (child: file sent ok)\n");
    else
    printf("Potomny: blad przy wysylaniu pliku (child: file sending error)\n"); //error at se
    fclose(plik);
    return;
}


int main(void)
{
    int gn_nasluch, gn_klienta; //gn_listen, gn_of_the_client
    struct sockaddr_in adr;
    socklen_t dladr = sizeof(struct sockaddr_in);

    gn_nasluch = socket(PF_INET, SOCK_STREAM, 0);
    adr.sin_family = AF_INET;
    adr.sin_port = PORT;
    adr.sin_addr.s_addr = INADDR_ANY;
    memset(adr.sin_zero, 0, sizeof(adr.sin_zero));

    if (bind(gn_nasluch, (struct sockaddr*) &adr, dladr) < 0)
    {
    printf("Glowny: bind nie powiodl sie (Parent: bind failed)\n");
    return 1;
    }

    listen(gn_nasluch, 10);

    while(1)
    {
    dladr = sizeof(struct sockaddr_in);
    gn_klienta = accept(gn_nasluch, (struct sockaddr*) &adr, &dladr);
    if (gn_klienta < 0)
    {
        printf("Glowny: accept zwrocil blad (Parent: accept error)\n");
        continue;
    }
    printf("Glowny: polaczenie od (Parent: connection from) %s:%u\n",
        inet_ntoa(adr.sin_addr),
        ntohs(adr.sin_port)
        );
    printf("Glowny: tworze proces potomny (Parent: I'm creating child process)\n");
    if (fork() == 0)
    {
        /* proces potomny */
        printf("Potomny: zaczynam obsluge (Child: start serving)\n");
        ObsluzPolaczenie(gn_klienta);
        printf("Potomny: zamykam gniazdo (Child: closing socket)\n");
        close(gn_klienta);
        printf("Potomny: koncze proces (Child: end of the process)\n");
        exit(0);
    }
    else
    {
        /* proces macierzysty */
        printf("Glowny: wracam do nasluchu (parent: return to listening)\n");
        continue;
    }
    }
    return 0;
}

uwaga: portal używa ciasteczek tylko do obsługi tzw. sesji...